package org.spamforces.web.page;

import com.google.inject.Inject;
import org.jacuzzi.core.DatabaseException;
import org.nocturne.annotation.Action;
import org.nocturne.annotation.Parameter;
import org.nocturne.link.Link;
import org.nocturne.validation.LengthValidator;
import org.nocturne.validation.RequiredValidator;
import org.nocturne.validation.ValidationException;
import org.nocturne.validation.Validator;
import org.spamforces.dao.RecipientProviderDao;
import org.spamforces.model.RecipientProvider;
import org.spamforces.model.Recipient;
import org.spamforces.utils.XMLHelper;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

/**
 * @author MikeMirzayanov (mirzayanovmr@gmail.com)
 */
@Link("providers")
public class RecipientProvidersManagePage extends WebPage {
    @Inject
    private RecipientProviderDao recipientProviderDao;

    @Parameter
    private Long emailProviderId;

    @Parameter(stripMode = Parameter.StripMode.SAFE)
    private String title;

    @Parameter(stripMode = Parameter.StripMode.NONE)
    private String url;

    @Parameter(stripMode = Parameter.StripMode.SAFE)
    private String login;

    @Parameter(stripMode = Parameter.StripMode.NONE)
    private String password;

    @Override
    public String getTitle() {
        return $("Recipient providers");
    }

    @Override
    public void action() {
        List<RecipientProvider> providers = recipientProviderDao.findAll();
        put("providers", providers);
    }

    @Action("delete")
    public void onDelete() {
        if (emailProviderId == null) {
            return;
        }
        try {
            RecipientProvider victim = recipientProviderDao.find(emailProviderId);
            if (victim == null) {
                setMessage($("Database error: provider hasn't been removed"));
            } else {
                recipientProviderDao.delete(victim);
                setMessage($("Provider has been removed"));
            }
        } catch (DatabaseException e) {
            setMessage($("Database error: provider hasn't been removed"));
        }
        abortWithRedirect(RecipientProvidersManagePage.class);
    }

    @Action("edit")
    public void onEdit() {
        skipTemplate();

        addValidator("title", new RequiredValidator());
        addValidator("title", new LengthValidator(2, 64));

        addValidator("url", new Validator() {
            @Override
            public void run(String value) throws ValidationException {
                try {
                    URL urlInstance = new URL(value);
                    if (!urlInstance.getProtocol().equals("http")) {
                        throw new ValidationException(
                                $("Please, enter HTTP URL"));
                    }
                } catch (MalformedURLException e) {
                    throw new ValidationException($("Please, enter valid URL"));
                }
            }
        });

        addValidator("login", new LengthValidator(0, 64));
        addValidator("password", new LengthValidator(0, 64));

        if (runValidationAndPrintErrors()) {
            RecipientProvider provider;

            if (emailProviderId != null) {
                provider = recipientProviderDao.find(emailProviderId);
            } else {
                provider = new RecipientProvider();
            }

            if (provider != null) {
                provider.setTitle(title);
                provider.setUrl(url);
                provider.setLogin(login);
                provider.setPassword(password);
                recipientProviderDao.save(provider);

                if (emailProviderId != null) {
                    setMessage($("Provider has been updated"));
                } else {
                    setMessage($("Provider has been added"));
                }

                printJson("success", "true");
            }
        }
    }

    @Action("test")
    public void onTest() {
        String delimiter = ", ";
        skipTemplate();

        RecipientProvider provider = null;
        if (emailProviderId != null) {
            provider = recipientProviderDao.find(emailProviderId);
        }
        if (provider == null) {
            printJson("success", "false");
            printJson("error", "no such provider");
            return;
        }

        try {
            Map<Recipient, Map<String, String>> response = XMLHelper.processXML(provider);
            Map<String, String> jsonResponse = new TreeMap<>();
            for (Recipient recipient : response.keySet()) {
                String params = "";
                Map<String, String> p = response.get(recipient);
                for (String key : p.keySet()) {
                    if (!params.isEmpty()) {
                        params += delimiter;
                    }
                    params += key + '=' + p.get(key);
                }
                jsonResponse.put(recipient.toString(), params);
            }
            printJson(jsonResponse);
        } catch (Exception e) {
            printJson("success", "false", "error", e.getMessage());
            e.printStackTrace();
        }
    }
}
